#include "operand.h"
#include "tree.h"
#include "line.h"
#include <iostream>

using namespace std;

Line::Line(vector<Line*> *childLines, LineType type, Condition* condition, LinePeriodicity periodicity, int timing, OpTreeNode* src)
{
	this->childLines = childLines;
	this->type = type;
	this->condition = condition;
	this->periodicity = periodicity;
	this->timing = timing;
	this->src = src;
}

void Line::PrintLine()
{
	if ( this->type == LINE_ALWAYS ) cout << "always @ ";
	else
	{
		if ( condition != NULL ) 
		{
			cout << "if (";
			condition->GetSrc()->Print();
			cout << ") ";
		}
	}
	if ( src != NULL ) src->Print();
	cout << endl;
}

bool Line::Execute(int cycle)
{
	bool isExecuted = false;
	if ( ( this->periodicity == LINE_EVERY_CYCLE ) ||
		 ( ( this->periodicity == LINE_ONE_CYCLE ) && ( this->timing == cycle ) ) ||
		 ( ( this->periodicity == LINE_PERIODICALLY ) && ( cycle%this->timing == 0 ) ) || 
		 ( ( this->periodicity == LINE_AFTER_CYCLE ) && ( this->timing >= cycle ) ) )
	{
		if ( !condition ||
			  ( condition && (condition->GetState() == true) ) )
		{
				src->Execute();
				isExecuted = true;
		}
	}
	
	if ( isExecuted )
	{
		cout << "executing line ... ";
		this->PrintLine();
		this->ExecuteChilds(cycle);
	}

	return isExecuted;
}

void Line::ExecuteChilds(int cycle)
{
	if (!childLines) return;

	for(vector<Line*>::iterator it = childLines->begin(); it != childLines->end(); it++)
	{
		(*it)->Execute(cycle);
	}
}

